#pragma once
#include<functional>
#include<string>
#include<signal.h>
#include"log.hpp"
#include"Socket.hpp"
using namespace std;
using func_t =function<string (string &package)>;

class TcpServer
{
public:
    TcpServer(uint16_t port,func_t callback):port_(port),callback_(callback)
    {}
    bool InitServer()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        lg(Info,"Init server ... done");
        return true;
    }
    void Start()
    {
        signal(SIGCHLD,SIG_IGN);//忽略子进程退出信号，自动回收子进程资源
        signal(SIGPIPE,SIG_IGN);//忽略管道破裂信号，避免程序意外退出
        while(true)//持续接收客户端连接
        {
            string clientip;
            uint16_t clientport;
            int sockfd=listensock_.Accept(&clientip,&clientport);
            if(sockfd<0)
            continue;
            lg(Info,"accept a new link, sockfd:%d,clientip:%s,clientport:%d",sockfd,clientip.c_str(),clientport);
            if(fork()==0)
            {
                listensock_.Close();
                string inbuffer_stream;
                while(true)
                {
                    char buffer[1280];
                    ssize_t n=read(sockfd,buffer,sizeof(buffer));
                    if(n>0)
                    {
                        buffer[n]=0;
                        inbuffer_stream+=buffer;//累计字节流，一次接收消息可能为多个或不完整

                        lg(Debug,"debug:\n%s",inbuffer_stream.c_str());
                        while(true)
                        {
                            string info=callback_(inbuffer_stream);
                            if(info.empty()) break;
                            lg(Debug,"debug response:\n%s",info.c_str());//显示处理过的信息
                            lg(Debug,"debug:\n%s",inbuffer_stream.c_str());//显示信息被处理过在减少
                            write(sockfd,info.c_str(),info.size());
                        }
                    }
                    else if(n==0)
                    break;
                    else break;
                }
                exit(0);
            }
            close(sockfd);
        }
    }
    ~TcpServer()
    {}
private:
    uint16_t port_;
    Sock listensock_;
    func_t callback_;
};